#include"temp.h"
//延时函数
void Delay1ms(uint y)
{
	uint x;
	for( ; y>0; y--)
	{
		for(x=110; x>0; x--);
	}
}
//ds18b20初始化
uchar Ds18b20Init()
{
	uchar i;
	DSPORT = 0; //将总线拉低 480us
	i = 70;
	while(i--);//延时 642us
	DSPORT = 1; //然后拉高总线，如果 DS18B20 做出反应会将在15us~60us 后总线拉低
	i = 0;
	while(DSPORT) //等待 DS18B20 拉低总线
	{
		Delay1ms(1);
		i++;
		if(i>5)//等待>5MS
		{
			return 0;//初始化失败
		}
	}
	return 1;//初始化成功
}
//向 18B20 写入一个字节
void Ds18b20WriteByte(uchar dat)
{
	uint i, j;
	for(j=0; j<8; j++)
	{
		DSPORT = 0; //每写入一位数据之前先把总线拉低 1us
		i++;
		DSPORT = dat & 0x01; //然后写入一个数据，从最低位开始
		i=6;
		while(i--); //延时 68us，持续时间最少60us
		DSPORT = 1; //然后释放总线，至少 1us 给总线恢复时间才能接着写入第二个数值
		dat >>= 1;
	}
}
//读取一个字节
uchar Ds18b20ReadByte()
{
	uchar byte, bi;
	uint i, j;
	for(j=8; j>0; j--)
	{
		DSPORT = 0;//先将总线拉低 1us
		i++;
		DSPORT = 1;//然后释放总线
		i++;
		i++;//延时 6us 等待数据稳定
		bi = DSPORT; //读取数据，从最低位开始读取
/*将 byte 左移一位，然后与上右移 7 位后的 bi，注意移动之后移掉那位补 0。*/
		byte = (byte >> 1) | (bi << 7);
		i = 4; //读取完之后等待 48us 再接着读取下一个数
		while(i--);
	}
	return byte;
}
//让 18b20 开始转换温度
void Ds18b20ChangTemp()
{
	Ds18b20Init();
	Delay1ms(1);
	Ds18b20WriteByte(0xcc); //跳过 ROM 操作命令
	Ds18b20WriteByte(0x44); //温度转换命令
	//Delay1ms(100); //等待转换成功，而如果你是一直刷着的话，就不用这个延时了
}
//发送读取温度命令
void Ds18b20ReadTempCom()
{
	Ds18b20Init();
	Delay1ms(1);
	Ds18b20WriteByte(0xcc); //跳过 ROM 操作命令
	Ds18b20WriteByte(0xbe); //发送读取温度命令
}
//读取温度
int Ds18b20ReadTemp()
{
	int temp = 0;
	uchar tmh, tml;
	Ds18b20ChangTemp(); //先写入转换命令
	Ds18b20ReadTempCom(); //然后等待转换完后发送读取温度命令
	tml = Ds18b20ReadByte(); //读取温度值共 16 位，先读低字节
	tmh = Ds18b20ReadByte(); //再读高字节
	temp = tmh;
	temp <<= 8;
	temp |= tml;
	return temp;
}